package com.fxp.project.jiuselu.web.file.domain;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * @Description: 阿里云 oss 上传工具类(高依赖版)
 * @Date: 2019/5/10
 */
@Slf4j
@Component
@ConfigurationProperties(prefix = "oss")
public class OssBootUtil {

    private static final String endPoint="oss-cn-hangzhou.aliyuncs.com";
    private static final String accessKeyId="LTAI5tC9qahALw3bS35imsh9";
    private static final String accessKeySecret="evkPtElSHTLsdLfqqtYZrr5roWboHy";
    private static final String bucketName="jiuselufile";
    private static final String staticDomain="";

    /**
     * oss 工具客户端
     */
    private static OSSClient ossClient = null;

    public static void main(String[] args) {

    }

    /**
     * 文件上传
     * @param file 文件
     * @param fileDir 文件保存目录
     * @return 返回文件url
     */
    public static String upload(MultipartFile file, String fileDir) {
        return upload(file, fileDir,null);
    }

    /**
     * 上传文件至阿里云 OSS
     * 文件上传成功,返回文件完整访问路径
     * 文件上传失败,返回 null
     *
     * @param file    待上传文件
     * @param fileDir 文件保存目录
     * @return oss 中的相对文件路径
     */
    public static String upload(MultipartFile file, String fileDir,String customBucket) {
        String FILE_URL;
        initOSS();
        StringBuilder fileUrl = new StringBuilder();
        String newBucket = bucketName;


        if (StringUtils.isNotEmpty(customBucket)){
            newBucket = customBucket;
        }

        try {
            //判断桶是否存在,不存在则创建桶
            if(!ossClient.doesBucketExist(newBucket)){
                ossClient.createBucket(newBucket);
            }
            if(!ossClient.doesBucketExist(newBucket)){
                ossClient.createBucket(newBucket);
            }
            // 获取文件名
            String orgName = file.getOriginalFilename();
            if("".equals(orgName)){
                orgName=file.getName();
            }
            assert orgName != null;
            orgName = getFileName(orgName);
            String fileName = !orgName.contains(".")
                    ?orgName + "_" + System.currentTimeMillis()
                    :orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
            if (!fileDir.endsWith("/")) {
                fileDir = fileDir.concat("/");
            }
            //update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符，防止攻击
            fileDir=filter(fileDir);
            //update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符，防止攻击
            fileUrl.append(fileDir).append(fileName);

            if (StringUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
                FILE_URL = staticDomain + "/" + fileUrl;
            } else {
                FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
            }
            PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
            // 设置权限(公开读)
//            ossClient.setBucketAcl(newBucket, CannedAccessControlList.PublicRead);
            if (result != null) {
                log.info("------OSS文件上传成功------" + fileUrl);
            }
//            ossClient.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return FILE_URL;
    }


    private static void initOSS() {
        if (ossClient == null) {
            ossClient = new OSSClient(OssBootUtil.endPoint,new DefaultCredentialProvider(OssBootUtil.accessKeyId, OssBootUtil.accessKeySecret),new ClientConfiguration());
        }
    }

    /**
     * 判断文件名是否带盘符，重新处理
     * @param fileName 文件名
     * @return 文件名称
     */
    public static String getFileName(String fileName){
        //判断是否带有盘符信息
        // Check for Unix-style path
        int unixSep = fileName.lastIndexOf('/');
        // Check for Windows-style path
        int winSep = fileName.lastIndexOf('\\');
        // Cut off at latest possible point
        int pos = (Math.max(winSep, unixSep));
        if (pos != -1)  {
            // Any sort of path separator found...
            fileName = fileName.substring(pos + 1);
        }
        //替换上传文件名字的特殊字符
        fileName = fileName.replace("=","").replace(",","").replace("&","")
                .replace("#", "").replace("“", "").replace("”", "");
        //替换上传文件名字中的空格
        fileName=fileName.replaceAll("\\s","");
        return fileName;
    }

    public static String filter(String str) throws PatternSyntaxException {
        // 清除掉所有特殊字符
        String regEx = "[`_《》~!@#$%^&*()+=|{}':;',\\[\\].<>?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }
}
